package com.wuxi.common.utils;

import com.wuxi.common.config.ShardingProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 统计查询工具类，用于对历史分表进行统计分析
 */
@Component
@RequiredArgsConstructor
public class StatisticQueryUtil {

    private final JdbcTemplate jdbcTemplate;
    private final ShardingProperties shardingProperties;

    private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyyMM");

    /**
     * 生成指定日期范围内的分表名列表
     */
    public List<String> getTableNamesInRange(String baseTableName, LocalDate startDate, LocalDate endDate) {
        List<String> tableNames = new ArrayList<>();

        if (!shardingProperties.getTables().contains(baseTableName)) {
            return tableNames;
        }

        LocalDate current = startDate;
        while (!current.isAfter(endDate)) {
            String tableName = ShardingUtil.getShardingTableName(baseTableName, current);
            tableNames.add(tableName);
            current = current.plusMonths(1);
        }

        return tableNames;
    }

    /**
     * 生成跨表统计查询SQL
     */
    public String buildUnionSql(String baseTableName, LocalDate startDate, LocalDate endDate, String sqlTemplate) {
        List<String> tableNames = getTableNamesInRange(baseTableName, startDate, endDate);
        if (tableNames.isEmpty()) {
            return "SELECT 0";
        }

        StringBuilder unionSql = new StringBuilder();
        for (int i = 0; i < tableNames.size(); i++) {
            String tableName = tableNames.get(i);
            String sql = sqlTemplate.replace("${tableName}", tableName);

            if (i > 0) {
                unionSql.append(" UNION ALL ");
            }
            unionSql.append(sql);
        }

        return unionSql.toString();
    }

    /**
     * 执行跨表统计查询
     */
    public <T> T executeStatisticQuery(String baseTableName, LocalDate startDate, LocalDate endDate,
                                       String sqlTemplate, Class<T> requiredType) {
        String sql = buildUnionSql(baseTableName, startDate, endDate, sqlTemplate);
        return jdbcTemplate.queryForObject(sql, requiredType);
    }
}